import { Role } from './role';
import { Password } from '../utils/password';
import { Collections, MongoDb } from '../utils/mongo';

const getUuid = require('../utils/uuid');

export class User {
	constructor() {
	}

	public commit() {
		MongoDb.getCollection(Collections.USERS).updateOne({id: this.id}, {$set: this}, {upsert: true});
	}

	public delete() {
		this.isDeleted = true;
		this.commit();
	}

	public verifyEmail() {
		this.isVerified = true;
		this.commit();
	}

	public addCredit(credit: number) {
		this.credit += credit;
		this.commit();
	}

	public verify(plainPassword: string) {
		return Password.verify(plainPassword, this.password);
	}

	public getRole() {
		return this.role;
	}

	public getEmail() {
		return this.email;
	}

	public getName(): string {
		return this.name;
	}

	public verified() {
		return this.isVerified;
	}

	public deleted() {
		return this.isDeleted;
	}

	public setEmail(email: string) {
		this.email = email;
	}

	public setPassword(plainPassword: string) {
		this.password = Password.getHashedPassword(plainPassword);
	}

	public static async getUserFromName(name: string): Promise<User> {
		return MongoDb.findOne(Collections.USERS, {name: name}, User);
	}

	public static createUser(name: string, plainPassword: string, email: string) {
		let instance = new User();
		instance.id = getUuid();
		instance.name = name;
		instance.creationTime = (new Date()).getTime();
		instance.credit = 0;
		instance.email = email;
		instance.isDeleted = false;
		instance.isVerified = false;
		instance.password = Password.getHashedPassword(plainPassword);
		return instance;
	}

	public static isUserPresent(name: string): Promise<Boolean> {
		return new Promise<Boolean>((resolve) => {
			MongoDb.getCollection(Collections.USERS).find({name: name}).count().then(count => resolve(count > 0));
		});
	}

	public static getUsers(): Promise<Array<User>> {
		return MongoDb.getCollection<User>(Collections.USERS).find({}).toArray();
	}

	public static getUserFromUid(uid: string): Promise<User> {
		return MongoDb.findOne(Collections.USERS, {id: uid}, User);
	}

	private id: string = '(null)';
	private name: string = '(null)';
	private creationTime: number = 0;
	private credit: number = 0;
	private email: string = '';
	private password: string = '';
	private isDeleted: boolean = true;
	private isVerified: boolean = false;
	private role: Role = new Role();
}
